﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace BigPixels
{
    public class PixelGrid
    {
        private Cell[,] pixels;

        public PixelGrid(int width, int height, Rectangle rect)
        {
            if (width <= 0)
                throw new ArgumentOutOfRangeException("width");

            if (height <= 0)
                throw new ArgumentOutOfRangeException("height");

            this.GridSize = new Size(width, height);
            this.pixels = new Cell[width, height];

            for (int x = 0; x < width; ++x)
            {
                for (int y = 0; y < height; ++y)
                {
                    this.pixels[x,y] = new Cell(x, y, Color.Empty, BoundsFromGrid(x, y, rect));
                }
            }

            //var upperLeft = new Point((int)(0.25 * rect.Width), (int) (0.25 * rect.Height));
            //var upperRight = new Point((int)(0.75 * rect.Width), (int)(0.25 * rect.Height));
            //var lowerLeft = new Point((int)(0.25 * rect.Width), (int)(0.75 * rect.Height));
            //var lowerRight = new Point((int)(0.75 * rect.Width), (int)(0.75 * rect.Height));

            //var p1 = At(upperLeft, rect);
            //var p2 = At(upperRight, rect);
            //var p3 = At(lowerLeft, rect);
            //var p4 = At(lowerRight, rect);
        }

        public Cell this[int x, int y]
        {
            get
            {
                if (x < 0 || x >= this.GridSize.Width)
                    throw new ArgumentOutOfRangeException("x");

                if (y < 0 || y >= this.GridSize.Height)
                    throw new ArgumentOutOfRangeException("y");

                return pixels[x, y];
            }
        }

        public Cell At(Point p, Rectangle client)
        {
            //if (p.X < 0 || p.X >= this.GridSize.Width)
            //    throw new ArgumentOutOfRangeException("p");

            //if (p.Y < 0 || p.Y >= this.GridSize.Height)
            //    throw new ArgumentOutOfRangeException("p");

            var pt = PixelFromPoint(p, client);

            return this[pt.X, pt.Y];
        }

        public Size GridSize
        {
            get;
            private set;
        }

        public int TotalPixels
        {
            get
            {
                return this.GridSize.Width * this.GridSize.Height;
            }
        }

        private Rectangle BoundsFromGrid(int x, int y, Rectangle client)
        {
            int rectangleHeight = Math.Max(client.Height / this.GridSize.Height, 1);
            int rectangleWidth = Math.Max(client.Width / this.GridSize.Width, 1);

            var rect = new Rectangle()
            {
                X = x * rectangleWidth,
                Y = y * rectangleHeight,
                Width = rectangleWidth,
                Height = rectangleHeight
            };
            
            return rect;
        }

        private Point PixelFromPoint(Point p, Rectangle client)
        {
            int rectangleHeight = Math.Max(client.Height / this.GridSize.Height, 1);
            int rectangleWidth = Math.Max(client.Width / this.GridSize.Width, 1);

            int x = (p.X / rectangleWidth);
            int y = (p.Y / rectangleHeight);

            return new Point(x, y);
        }

        public void UpdateBounds(Rectangle r)
        {
            for (int x = 0; x < this.GridSize.Width; ++x)
            {
                for (int y = 0; y < this.GridSize.Height; ++y)
                {
                    this.pixels[x, y].Bounds = BoundsFromGrid(x, y, r);
                }
            }
        }
    }
}
